/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bs.coregamelibrary.protocoltea.codec;

import com.google.protobuf.CodedOutputStream;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.Serializable;

/**
 * only use for original message type
 *
 * @author dungpt
 */
public class Message implements Serializable {

    private static final long serialVersionUID = 1L;
    //private Session session;
    public final int command;
    public int subCommand = 0;
    private ByteArrayOutputStream os = null;
    public DataOutputStream dos = null;
    private ByteArrayInputStream is = null;
    public DataInputStream dis = null;
    private byte[] bytes = null;
    private byte[] messageData = null;
    private String userId;

    /**
     * Them status cho protocol 10.
     *
     * @param command cmd id
     * @param subCommand
     */
    public Message(int command, int subCommand) {
        this.command = command;
        this.subCommand = subCommand;
        os = new ByteArrayOutputStream();
        dos = new DataOutputStream(os);

    }

    public Message(int command, byte[] data) {
        this(command, 0, data);
    }

    public Message(int command, int subCommand, byte[] data) {
        this.command = command;
        this.subCommand = subCommand;

        is = new ByteArrayInputStream(data);
        dis = new DataInputStream(is);
        messageData = data.clone();
    }

    public ByteBuf toByteBuf() throws IOException {
        final byte data[] = toByteArray();
        final CodedOutputStream outputStream = CodedOutputStream.newInstance(data);
        outputStream.checkNoSpaceLeft();
        return Unpooled.wrappedBuffer(data);
    }

    /**
     * User for new protocol
     *
     * @param tea
     * @return
     */
    public byte[] toByteArray() throws IOException {
        byte[] data = null;
        // cache lai data neu chua cache
        if (bytes == null) {
            ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
            DataOutputStream dos1 = new DataOutputStream(bos1);
            dos1.writeInt(command);
            dos1.writeInt(subCommand);
            if (dos != null) {
                dos.flush();
                data = os.toByteArray();
                if (data.length > 0) {
                    dos1.write(data);
                }
                dos.close();
            }
            byte[] byteEncrypt;
            byteEncrypt = bos1.toByteArray();
            dos1.close();
            ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
            dos1 = new DataOutputStream(baos1);
            dos1.writeInt(byteEncrypt.length);
//            dos1.write(byteEncrypt);
            bytes = baos1.toByteArray();
            dos1.close();
        }
        return bytes;
    }

    public byte[] getMessageData() {
        return messageData.clone();
    }

    public void cleanup() throws IOException {
        if (dis != null) {
            dis.close();
        }
        if (dos != null) {
            dos.close();
        }
        bytes = null;
    }

    @Override
    public String toString() {
        return "Message{" + "command=" + command + ", subCommand=" + subCommand + ", userId=" + userId + '}';
    }

    /**
     * @return the userId
     */
    public String getUserId() {
        return userId;
    }

    /**
     * @param userId the userId to set
     */
    public void setUserId(String userId) {
        this.userId = userId;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return (Message) super.clone();
    }

}
